package main // 声明 main 包，表明当前是一个可执行程序

// 导入内置 fmt 包

// func main() { // main函数，是程序执行的入口
// 	fmt.Println("Hello World!") // 在终端打印 Hello World!

// }

// func main() {
// 	// var array = [...]int{0, 1, 2, 3, 4, 5, 6} //创建有7个int型元素的数组
// 	// s1 := array[0:4]
// 	// s2 := array[:4]
// 	// s3 := array[2:]
// 	// fmt.Print("%v\n", s1) //[0 1 2 3]
// 	// fmt.Print("%v\n", s2) //[0 1 2 3]
// 	// fmt.Print("%v\n", s3) //[2 3 4 5 6]

// 	// // len = 10， cap = 10
// 	// a := make([]int, 10)

// 	// //len = 10, cap = 15
// 	// b := make([]int, 10, 15)
// 	// fmt.Print("%v\n", a) // 结果未[0 0 0 0 0 0 0 0 0 0]
// 	// fmt.Print("%v\n", b) // 结果未[0 0 0 0 0 0 0 0 0 0]

// 	// 	ma := map[string]int{"a": 1, "b": 2}
// 	// 	fmt.Println(ma["a"])
// 	// 	fmt.Println(ma["b"])

// 	// 	// make(map[K]T)      //map的容量使用默认值
// 	// 	// make(map[K]T, len) //map 的容量使用给定的len值

// 	// 	mp1 := make(map[int]string)
// 	// 	mp2 := make(map[int]string, 10)
// 	// 	mp1[1] = "tom"
// 	// 	mp2[1] = "pony"
// 	// 	fmt.Println(mp1[1]) //tom
// 	// 	fmt.Println(mp2[1]) //pony
// 	//
// 	// type User struct {
// 	// 	name string
// 	// 	age  int
// 	// }

// 	// ma := make(map[int]User)
// 	// andes := User{
// 	// 	name: "andesname",
// 	// 	age:  18,
// 	// }

// 	// ma[1] = andes
// 	// //ma[1].age = 19 //ERROR,不能通过map引用直接修改
// 	// andes.age = 19
// 	// fmt.Print("%v\n", ma)

// 	// ma[1] = andes //必须整体替换value
// 	// fmt.Print("%v\n", ma)

// 	switch i := "y"; i { //switch后面可以带上一个初始化的语句
// 	case "y", "Y": //多个case值使用逗号分隔
// 		fmt.Println("yes") //yes
// 		fallthrough        //fallthrough 会跳过接下来的case条件表达式直接执行一下case语句
// 	case "n", "N":
// 		fmt.Println("no") //no
// 	}
// }

// func chvalue(a int) int {
// 	a = a + 1
// 	return a
// }

// func chpointer(a *int) {
// 	*a = *a + 1
// 	return
// }

// func main() {
// 	a := 10
// 	chvalue(a) //实参传递给形参时值拷贝
// 	fmt.Println(a)

// 	chpointer(&a) //实参传递给形参时值拷贝,只不过复制的时a的地址值
// 	fmt.Println(a)

// }

// func sum(arr ...int) (sum int) {

// 	for _, v := range arr { //此时arr就相当于切片，可以使用range访问
// 		sum += v
// 	}
// 	return
// }

// func main() {
// 	a := sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
// 	fmt.Println(a)
// }

// func sum(arr ...int) (sum int) {
// 	for _, v := range arr {
// 		sum += v
// 	}
// 	return
// }

// func main() {
// 	slice := []int{1, 2, 3, 4}
// 	//array := [...]int{1, 2, 4, 5} 数组不可以作为实参传递给不定参的函数

// 	a := sum(slice...)
// 	fmt.Println(a)
// }

// func suma(arr ...int) (sum int) {
// 	for _, v := range arr {
// 		sum += v
// 	}
// 	return
// }

// func sumb(arr []int) (sum int) {
// 	for v := range arr {
// 		sum += v
// 	}
// 	return
// }

// //suma 和sumb的类型并不一样
// func main() {
// 	fmt.Printf("%T\n", suma) // func(...int) int
// 	fmt.Printf("%T\n", sumb) // func([]int) int
// }

// func add(a, b int) int {
// 	return a + b
// }

// func main() {
// 	fmt.Printf("%T\n", add)
// }

// func add(a, b int) int {
// 	return a + b
// }

// func sub(a, b int) int {
// 	return a - b
// }

// type Op func(int, int) int //定义一个函数类型，输入的是两个int类型，返回值是一个int类型

// func do(f Op, a, b int) int { // 定义一个函数，第一个参数是函数类型Op
// 	return f(a, b) //函数类型变量可以直接用来进行函数调用
// }

// func main() {
// 	a := do(add, 1, 2) // 函数名add可以当作相同函数类型形参，不需要强制类型转换
// 	fmt.Println(a)     //3
// 	s := do(sub, 1, 2)
// 	fmt.Println(s) //-1
// }

// func sum(a, b int) int {
// 	return a + b
// }

// func main() {
// 	fmt.Println(sum(3, 4)) //直接调用
// 	f := sum               //有名函数可以直接赋值给变量
// 	fmt.Println(f(1, 2))

// }

// //匿名函数别直接赋值给函数变量,使用时候相当使用了有名函数定义
// var sum = func(a, b int) int {
// 	return a + b
// }

// //函数使用匿名函数作为参数。实际上就是函数的开始地址。
// func doinput(f func(int, int) int, a, b int) int {
// 	return f(a, b)
// }

// //匿名函数作为返回值
// func wrap(op string) func(int, int) int {
// 	switch op {
// 	case "add":
// 		return func(a, b int) int {
// 			return a + b
// 		}
// 	case "sub":
// 		return func(a, b int) int {
// 			return a - b
// 		}
// 	default:
// 		return nil
// 	}
// }

// func main() {
// 	//匿名函数直接被调用
// 	defer func() {
// 		if err := recover(); err != nil {
// 			fmt.Println(err)
// 		}
// 	}()

// 	sum(1, 2)

// 	//匿名函数作为实参
// 	doinput(func(x, y int) int {
// 		return x + y
// 	}, 1, 2)

// 	opFunc := wrap("add")
// 	re := opFunc(2, 3)

// 	fmt.Println(re)

// 	opFunctwo := wrap("sub")
// 	retwo := opFunctwo(2, 3)
// 	fmt.Println(retwo)

// }

// func main() {
// 	//先进后出
// 	defer func() {
// 		println("first")
// 	}()

// 	defer func() {
// 		println("second")
// 	}()

// 	println("function body")

// }

// func f() int {
// 	a := 0
// 	defer func(i int) {
// 		println("defer i=", i)
// 	}(a)

// 	a++
// 	return a
// }

// func main() {
// 	f()
// }

// func main() {
// 	defer func() {
// 		println("first")
// 	}()

// 	a := 0
// 	println(a)
// 	return

// 	defer func() {
// 		println("second")
// 	}()
// }

// import "os"

// func main() {
// 	//defer 不会被延迟执行，也不会被执行
// 	defer func() {
// 		println("defer")
// 	}()

// 	println("func body")

// 	os.Exit(1)
// }

// func CopyFile(dst, src string) (w int64, err error) {
// 	src, err := os.Open(src)
// 	if err != nil {
// 		return
// 	}

// 	dst, err := os.Create(dst)
// 	if err != nil {
// 		//src很容易被忘记关闭
// 		src.Close()
// 		return
// 	}

// 	w, err = io.Copy(dst, src)

// 	dst.Close()
// 	src.Close()
// 	return
// }

// func CopyFile(dst, src string) (w int64, err error) {
// 	newsrc, err := os.Open(src)
// 	if err != nil {
// 		return
// 	}
// 	defer newsrc.Close()

// 	newdst,err:=os.Create(dst)
// 	if err != nil {
// 		return
// 	}

// 	defer newdst.Close()

// 	w, err = io.Copy(newdst,newsrc)

// 	return
// }

// func CopyFile(dst, src string) (w int64, err error) {
// 	newsrc, err := os.Open(src)
// 	if err != nil {
// 		return
// 	}

// 	newdst, err := os.Create(dst)
// 	if err != nil {
// 		//src很容易被忘记关闭
// 		newsrc.Close()
// 		return
// 	}

// 	w, err = io.Copy(newdst, newsrc)

// 	newdst.Close()
// 	newsrc.Close()
// 	return
// }

// func fa(a int) func(i int) int {
// 	return func(i int) int {
// 		println(&a, a)
// 		a = a + 1
// 		return a
// 	}
// }

// func main() {
// 	f := fa(1) //f引用的外部的闭包环境包括本次函数调用的形参a的值1
// 	g := fa(1) //g引用的外部的闭包环境包括本次函数调用的形参a的值1

// 	//此时f、g引用的闭包环境中的a的值并不时同一个，而是两次函数调用产生的副本

// 	println(f(1))
// 	//多次调用f引用的时同一个副本a
// 	println(f(1))

// 	println("=================")

// 	//g中的a的值仍然是1
// 	println(g(1))
// 	println(g(1))

// }

// var (
// 	a = 0
// )

// func fa() func(i int) int {
// 	return func(i int) int {
// 		println(&a, a)
// 		a = a + 1
// 		return a
// 	}
// }

// func main() {
// 	f := fa() //f引用的外部的闭包环境包括全局变量a
// 	g := fa() //g引用的外部的闭包环境包括全局变量a

// 	//此时f、g引用的闭包环境中的a的值是同一个

// 	println(f(1)) //1
// 	println(g(1)) //2
// 	println(g(1)) //3
// 	println(g(1)) //4
// 	println(f(1)) //5
// 	println(f(1)) //6
// }

// func fa(base int) (func(int) int, func(int) int) {
// 	println(&base, base)
// 	add := func(i int) int {
// 		base += i
// 		println(&base, base)
// 		return base

// 	}

// 	sub := func(i int) int {
// 		base -= i
// 		println(&base, base)
// 		return base

// 	}

// 	return add, sub

// }

// func main() {
// 	// f、g闭包的引用的base是同一个，是fa函数调用传递过来的实参值
// 	f, g := fa(0)

// 	println("=============")

// 	// s、k闭包的引用的base是同一个，是fa函数调用传递过来的实参值
// 	s, k := fa(0)

// 	//f、g和s、k引用不同的闭包变量，这是由于fa每次调用都是重新分配形参
// 	println("=============")

// 	println(f(1), g(2))
// 	println("===============")
// 	println(s(1), k(2))

// }

// //这个会捕获失败
// defer recover()

// //这个会捕获失败
// defer fmt.println(recover())

// //这个嵌套两层也会捕获失败
// defer func(){
// 	func() {
// 		println("defer inner")
// 		recover()//无效
// 	}()
// }()

// //如下场景会捕获成功
// defer func() {
// 	println("defer inner")
// 	recover()
// }()

// func except(){
// 	recover()
// }

// func test(){
// 	defer except()
// 	panic("test panic")
// }

// func main() {
// 	defer func() {
// 		if err := recover(); err != nil {
// 			fmt.Println(err)
// 		}
// 	}()

// 	//只有最后一次panic调用能够被捕获
// 	defer func() {
// 		panic("first defer panic")
// 	}()

// 	defer func() {
// 		panic("second defer panic")
// 	}()

// 	panic("main body panic")
// }

// func do() {
// 	//这里并不能捕获da函数中的panic
// 	defer func() {
// 		if err := recover(); err != nil {
// 			fmt.Println(err)
// 		}
// 	}()

// 	go da()
// 	go db()
// 	time.Sleep(3 * time.Second)
// }

// func da() {
// 	panic("panic da")
// 	for i := 0; i < 10; i++ {
// 		fmt.Println(i)
// 	}
// }

// func db() {
// 	for i := 0; i < 10; i++ {
// 		fmt.Println(i)
// 	}
// }

// func main() {
// 	do()

// }

// go:noinline
// func swap(a, b int) (x int, y int) {
// 	x = b
// 	y = a
// 	return
// }

// func main() {
// 	fmt.Println(swap(10, 20))

// }

// func a(i int) func() {
// 	return func() {
// 		print(i)
// 	}
// }

// func main() {
// 	f := a(1)
// 	f()
// }

// //使用type声明的命名类型
// type Person struct {
// 	name string
// 	age  int
// }

// func main() {
// 	//使用struct字面量声明的是未命名类型
// 	a := struct {
// 		name string
// 		age  int
// 	}{"andes", 18}

// 	fmt.Printf("%T\n", a) //struct {name string; age int}
// 	fmt.Printf("%v\n", a) //{andes 18}

// 	b := Person{"tom", 21}
// 	fmt.Printf("%T\n", b) //main.Person
// 	fmt.Printf("%v\n", b) //{tom 21}
// }

// import "fmt"

// type Map map[string]string

// func (m Map) Print() {
// 	for _, key := range m {
// 		fmt.Println(key)
// 	}
// }

// type iMap Map

// //只要底层类型是slice、map等range的类型字面量，新类型仍然可以使用range迭代

// func (m iMap) Print() {
// 	for _, key := range m {
// 		fmt.Println(key)
// 	}
// }

// type slice []int

// func (s slice) Print() {
// 	for _, v := range s {
// 		fmt.Println(v)
// 	}
// }

// func main() {
// 	mp := make(map[string]string, 10)
// 	mp["hi"] = "tata"

// 	//mp与ma有相同的底层类型map[string]string,并且mp是未命名类型
// 	//所以mp可以直接赋值给ma
// 	var ma Map = mp

// 	//im 与ma虽然有相同的底层类型map[string]string,但它们中没有一个是未命名类型
// 	//不能赋值，如下语句不能通过编译
// 	//var im iMap = ma

// 	ma.Print() // tata
// 	// im.Print()

// 	//Map实现了Print(),所以其可以赋值给接口类型变量
// 	var i interface {
// 		Print()
// 	} = ma

// 	i.Print() //tata

// 	s1 := []int{1, 2, 3}
// 	var s2 slice
// 	s2 = s1
// 	s2.Print() //1 2 3
// }
// import "fmt"

// type Map map[string]string

// func (m Map) Print() {
// 	for _, key := range m {
// 		fmt.Println(key)
// 	}
// }

// type iMap Map

// //只要底层类型是slice、map等支持range的类型字面量，新类型仍然可以使用range迭代
// func (m iMap) Print() {
// 	for _, key := range m {
// 		fmt.Println(key)
// 	}
// }

// func main() {
// 	mp := make(map[string]string, 10)
// 	mp["hi"] = "tata"
// 	//mp与ma有相同的底层类型map[string]string,并且mp是未命名类型
// 	var ma Map = mp

// 	//im与ma虽然有相同的底层类型，但是二者中没有一个是字面量类型，不能直接赋值，可以
// 	//强制进行类型转换
// 	//var im iMap = ma
// 	var im iMap = (iMap)(ma)
// 	ma.Print()
// 	im.Print()
// }

// import "fmt"

// func main() {
// 	s := "hello,世界！"
// 	var a []byte
// 	a = []byte(s)
// 	var b string
// 	b = string(a)
// 	var c []rune
// 	c = []rune(s)
// 	fmt.Printf("%T\n", a) //[]uint8 byte是int8的别名
// 	fmt.Printf("%T\n", b) //string
// 	fmt.Printf("%T\n", c) //[]int32 rune是int32的别名
// }

// UTS Namespace的隔离
// import (
// 	"log"
// 	"os"
// 	"os/exec"
// 	"syscall"
// )

// func main() {
// 	cmd := exec.Command("sh")
// 	cmd.SysProcAttr = &syscall.SysProcAttr{
// 		Cloneflags: syscall.CLONE_NEWUTS,
// 	}

// 	cmd.Stdin = os.Stdin
// 	cmd.Stdout = os.Stdout
// 	cmd.Stderr = os.Stderr

// 	if err := cmd.Run(); err != nil {
// 		log.Fatal(err)
// 	}
// }

// //新类型继承运算

// import "fmt"

// type Map map[string]string

// func (m Map) Print() {
// 	//底层类型支持range运算，新类型可用
// 	for _, key := range m {
// 		fmt.Println(key)
// 	}
// }

// type MyInt int

// func main() {
// 	var a MyInt = 10
// 	var b MyInt = 10

// 	//int 类型支持的加减乘除运算，新类型同样可用
// 	c := a + b
// 	d := a * b

// 	fmt.Println(c)
// 	fmt.Println(d)
// }

// import "fmt"

// type Int int

// func (a Int) Max(b Int) Int {
// 	if a >= b {
// 		return a
// 	} else {
// 		return b
// 	}
// }

// func (i *Int) Set(a Int) {
// 	*i = a
// }

// func (i Int) Print() {
// 	fmt.Printf("value=%d\n", i)
// }

// func main() {
// 	var a Int = 10
// 	var b Int = 50

// 	c := a.Max(b)
// 	c.Print()    //value =50
// 	(&c).Print() //value =50 内部被编译器转换为c.Print()

// 	a.Set(20) //内部被编译器转化为(&a).Set(20)
// 	a.Print() //value =20

// 	(&a).Set(30)
// 	a.Print() //value = 30
// }

// type Data struct{}

// func (Data) TestValue(){}

// func (*Data) TestPointer(){}

// //这样字面量显式调用，无论值调用，还是表达式调用
// //编译器都不会进行方法集的自动转换，编译器会严格校验方法集

// //*Data方法集是TestPointer和TestValue
// //Data 方法集只有TestValue

// (*Data)(&struct{}{}).TestPointer() //显式的调用
// (*Data)(&struct{}{}).TestValue() //显式的调用

// (Data)(struct{}{}).TestValue() //method value
// Data.TestValue(struct{}{})    //method expression

// //如下调用因为方法集和不匹配而失败
// //Data . TestPoiter(struct{}{)) // type Data has no method TestPoiter
// //(Data) (struct {) {)) . TestPointer ( )	 //cannot call pointer method on Data(struct {) literal)

// type Data struct{}

// func (Data) TestValue()    {}
// func (*Data) TestPointer() {}

// func main() {
// 	//声明一个类型变量a
// 	var a Data = struct{}{}

// 	// 表达式调用编译器不会进行自动转换
// 	Data.TestValue(a)
// 	// Data.Test Value(&a)
// 	(*Data).TestValue(&a)
// 	// Data.TestPointer(&a) //type Data has no method TestPointer
// 	//值调用编译器会进行自动转换
// 	f := a.TestValue
// 	f()

// 	y := (&a).TestValue //编译器帮助转换 a.TestValue
// 	y()

// 	g := a.TestPointer //会转化为(&a).TestPointer
// 	g()

// 	x := (&a).TestPointer
// 	x()
// }

// =============================================

// type X struct {
// 	a int
// }

// type Y struct {
// 	X
// 	b int
// }

// type Z struct {
// 	Y
// 	c int
// }

// func main() {
// 	x := X{a: 1}

// 	y := Y{
// 		X: x,
// 		b: 2,
// 	}

// 	z := Z{
// 		Y: y,
// 		c: 3,
// 	}

// 	//z.a、 z.Y.X.a 三者是等价的， z.a z.Y.a 是 z.Y.X.a的简写

// 	println(z.a, z.Y.a, z.Y.X.a) // 1 1 1

// 	z = Z{}

// 	z.a = 2
// 	println(z.a, z.Y.a, z.Y.X.a) //2 2 2

// }

//======================================

// type X struct {
// 	a int
// }

// type Y struct {
// 	X
// 	a int
// }

// type Z struct {
// 	Y
// 	a int
// }

// func main() {
// 	x := X{a: 1}

// 	y := Y{
// 		X: x,
// 		a: 2,
// 	}

// 	z := Z{
// 		Y: y,
// 		a: 3,
// 	}

// 	//此时的z.a、z.Y.a、z.Y.X.a代表不同的字段

// 	println(z.a, z.Y.a, z.Y.X.a) // 3 2 1

// 	z = Z{}
// 	z.a = 4
// 	z.Y.a = 5
// 	z.Y.X.a = 6

// 	//此时的z.a、z.Y.a、z.Y.X.a代表不同的字段
// 	println(z.a, z.Y.a, z.Y.X.a) // 4 5 6

// }
// ==================================
// type X struct {
// 	a int
// }

// type Y struct {
// 	X
// 	b int
// }

// type Z struct {
// 	Y
// 	c int
// }

// func (x X) Print() {
// 	fmt.Printf("In X,a=%d\n", x.a)
// }

// func (x X) XPrint() {
// 	fmt.Printf("In X,a=%d\n", x.a)
// }

// func (y Y) Print() {
// 	fmt.Printf("In X,a=%d\n", y.b)
// }

// func (z Z) Print() {
// 	fmt.Printf("In X,a=%d\n", z.c)

// 	//显示的完全路径调用内嵌字段的方法
// 	z.Y.Print()
// 	z.Y.X.Print()
// }

// func main() {
// 	x := X{a: 1}

// 	y := Y{
// 		X: x,
// 		b: 2,
// 	}

// 	z := Z{
// 		Y: y,
// 		c: 3,
// 	}

// 	//从外向内查找，首先找到的是Z的Print()方法

// 	z.Print()

// 	fmt.Println()

// 	//从外向内查找，最后找到的是X的XPrint()方法
// 	z.XPrint()
// 	z.Y.XPrint()

// }

//===============================================

// type X struct {
// 	a int
// }

// type Y struct {
// 	X
// }

// type Z struct {
// 	*X
// }

// func (x X) Get() int {
// 	return x.a
// }

// func (x *X) Set(i int) {
// 	x.a = i
// }

// func main() {
// 	x := X{a: 1}

// 	y := Y{
// 		X: x,
// 	}

// 	println(y.Get()) //1

// 	//此处编译器做了自动转换
// 	y.Set(2)
// 	println(y.Get()) //2

// 	//为了不让编译器做自动转接，使用方法表达式调用方式
// 	//Y内嵌字段X，所以type Y的方法集是Get，type *Y的方法集是Set Get
// 	(*Y).Set(&y, 3)

// 	//type Y的方法集合并没有Set方法，所以下一句编译不能通过
// 	//Y.Set(y,3)

// 	println(y.Get()) //3

// 	z := Z{
// 		X: &x,
// 	}

// 	//按照嵌套字段的方法集的规则
// 	//Z内嵌字段*X，所以type Z和type *Z方法集都包含类型X定义的方法Get和Set

// 	//为了不让编译器做自动转换，仍然使用方法表达式调用方式

// 	Z.Set(z, 4)

// 	println(z.Get()) //4

// 	(*Z).Set(&z, 5)
// 	println(z.Get()) //5

// }
//===============================================

// //有名函数定义，函数名是add
// //add类型是函数字面量类型 func (int,int) int
// func add(a, b int) int {
// 	return a + b
// }

// //函数声明语句，用于Go代码调用汇编代码
// func add(int,int) int

// // add 函数的签名，实际上就是add的字面量类型
// func (int,int) int

// //匿名函数不能独立存在，常作为函数参数、返回值、或者赋值给某个变量
// //匿名函数可以直接显示初始化
// //匿名函数的类型也是函数字面量类型 func(int,int) int
// func (a,b int) int {
// 	return a+b
// }

// //新定义函数类型ADD
// //ADD底层类型是函数字面量类型func(int，int) int

// type ADD func(int, int) int

// // add 和ADD的底层类型相同，并且add是字面量类型
// //所以add可直接赋值给ADD类型的变量g
// var g ADD = add

// func main() {
// 	f := func(a, b int) int {
// 		return a + b
// 	}

// 	g(1, 2)
// 	f(1, 2)

// 	//f和add的函数签名相同
// 	fmt.Printf("%T\n", f)   //func(int,int) int
// 	fmt.Printf("%T\n", add) //func(int,int) int
// }
//===============================================

// //src/net/http/server.go

// //定义一个有名函数类型HandlerFunc
// type HandlerFunc func(ResponseWriter, *Request)

// //为有名函数类型添加方法
// //这是一种包装器的编程技法
// //ServerHTTP calls f(w, r)
// func (f HandlerFunc) ServerHTTP(w ResponseWriter, r *Request) {
// 	f(w, r)
// }

// //函数类型HandlerFunc 实现了接口Handler的方法
// type Handler interface {
// 	ServerHTTP(ResponseWrite, *Request)
// }

// func (mux *ServeMux) Handle(pattern string, handler handler)

// //所以HandlerFunc类型的变量可以传递给Handler接口变量
// func (mux *ServeMux) HandlerFunc(pattern string, handler func(ResponseWriter, *Request)) {
// 	mux.Handler(pattern, HandlerFunc(handler))
// }

//===============================================

// type Reader interface {
// 	Read(p []byte) (n int, err error)
// }

// type Writer interface {
// 	Write (p []byte) (n int, err error)
// }

// type ReadWriter interface {
// 	Reader
// 	Writer
// }

// type ReadWriter interface {
// 	Reader
// 	Write(p[]byte)(n int,err error)
// }

// type ReadWriter interface {
// 	Read(p []byte) (n int, err error)
// 	Write(p[]byte)(n int,err error)
// }

//===============================================

// import (
// 	"fmt"
// 	"io"
// )

// func main() {
// 	var i io.Reader
// 	fmt.Printf("%T\n", i)
// }
// import (
// 	"io"
// 	"os")

// file,_:= os.OpenFile("notes.txt", os.O_RDWR|os.O_CREATE, 0755)

// var rw io.ReadWriter  = file
// //io.ReadWriter 接口可以直接赋值给io.Writer接口变量
// var w io.Writer = rw
//===============================================

// type Printer interface {
// 	Print()
// }

// type S struct{}

// func (s S) Print() {
// 	println("print")
// }

// func main() {
// 	var i Printer

// 	//没有初始化的接口调用其方法会产生panic
// 	//pani： runtime error:invalid memory address or nil pointer derference
// 	//i.Print()

// 	//必须初始化
// 	i = S{}
// 	i.Print()
// }
//===============================================

// type Inter interface {
// 	Ping()
// 	Pang()
// }

// type Anter interface {
// 	Inter
// 	String()
// }

// type St struct {
// 	Name string
// }

// func (St) Ping() {
// 	println("ping")
// }

// func (*St) Pang() {
// 	println("pang")
// }

// func main() {
// 	st := &St{"andes"}
// 	var i interface{} = st

// 	//判断i绑定的实例是否实现了接口类型Inter
// 	o := i.(Inter)
// 	o.Pang()
// 	o.Ping()

// 	//如下语句会引发panic，因为i没有实现接口Anter
// 	//p := i.(Anter)
// 	//p.String()

// 	//判断i绑定的实例是否就是具体类型St
// 	s := i.(*St)
// 	fmt.Printf("%s", s.Name)

// }
//===============================================

// type Inter interface {
// 	Ping()
// 	Pang()
// }

// type Anter interface {
// 	Inter
// 	String()
// }

// type St struct {
// 	Name string
// }

// func (St) Ping() {
// 	println("ping")
// }

// func (*St) Pang() {
// 	println("pang")
// }

// func main() {
// 	st := &St{"andes"}
// 	var i interface{} = st

// 	//判断i绑定的实例是否实现了接口类型Inter
// 	if o, ok := i.(Inter); ok {
// 		o.Ping() //ping
// 		o.Pang() //pang
// 	}

// 	if p, ok := i.(Anter); ok {
// 		//i没有实现接口Anter，所以程序不会执行到这里
// 		p.String()
// 	}

// 	//判断i绑定的实例是否就是具体类型St
// 	if s, ok := i.(*St); ok {
// 		fmt.Printf("%s", s.Name) //andes
// 	}
// }
//===============================================

// import (
// 	"io"
// 	"log"
// 	"os"
// )

// func main() {

// 	f, err := os.OpenFile("notes.txt", os.O_RDWR|os.O_CREATE, 0755)
// 	if err != nil {
// 		log.Fatal(err)
// 	}

// 	defer f.Close()

// 	var i io.Reader = f

// 	switch v := i.(type) {
// 	//i的绑定的实例时*osFile类型，实现了io.ReadWriter接口，所以case匹配成功
// 	case io.Reader:
// 		//v是io.Reader接口类型，所以可以调用write方法
// 		v.Write([]byte("io.ReadWrite\n"))

// 	//由于上一个case已经匹配，就是这个case也匹配，也不会走到这里
// 	case *os.File:
// 		v.Write([]byte("*os.File\n"))
// 		v.Sync()
// 	default:
// 		return

// 	}
// }
//===============================================
// import (
// 	"io"
// 	"log"
// 	"os"
// )

// func main() {

// 	f, err := os.OpenFile("notes.txt", os.O_RDWR|os.O_CREATE, 0755)
// 	if err != nil {
// 		log.Fatal(err)
// 	}

// 	defer f.Close()

// 	var i io.Reader = f

// 	switch v := i.(type) {
// 	//匹配成功，v的类型就是具体类型*os.File
// 	case *os.File:
// 		v.Write([]byte("io.ReadWrite\n"))
// 		v.Sync()

// 	//由于上一个case已经匹配，就是这个case也匹配，也不会走到这里
// 	case io.ReadWriter:
// 		v.Write([]byte("*os.File\n"))
// 	default:
// 		return

// 	}
// }
//===============================================

// import "fmt"

// type Inter interface {
// 	Ping()
// 	Pang()
// }

// type St struct{}

// func (St) Ping() {
// 	println("ping")
// }

// func (*St) Pang() {
// 	println("pang")
// }

// func main() {
// 	var st *St = nil
// 	var it Inter = st

// 	fmt.Printf("%p \n", st)
// 	fmt.Printf("%p \n", it)

// 	if it != nil {
// 		it.Pang()

// 		//下面的语句会导致panic
// 		//方法转换为函数调用，第一个参数时St类型，由于*St是nil，无法获取指针所指的
// 		//对象的值，所以导致panic
// 		//it.Ping()
// 	}
// }
//===============================================

// type Caler interface {
// 	Add(a, b int) int
// 	Sub(a, b int) int
// }

// type Adder struct{ id int }

// //go:noinline
// func (adder Adder) Add(a, b int) int { return a + b }

// //go:noinline
// func (adder Adder) Sub(a, b int) int { return a - b }

// func main() {
// 	var m Caler = Adder{id: 1234}

// 	m.Add(10, 32)
// }
//===============================================

// import "testing"

// type identifier interface {
// 	idInline() int32
// 	idNOInline() int32
// }

// type id32 struct{ id int32 }

// func (id *id32) idInline() int32 { return id.id }

// //go:noinlie
// func (id *id32) idNOInline() int32 { return id.id }

// var escapeMePlease *id32

// //主要作用是强制变量内存在heap上分配
// //go：noinline
// func escapeToHeap(id *id32) identifier {
// 	escapeMePlease = id
// 	return escapeMePlease
// }

// //直接调用
// func BenchmarkMethodCall_direct(b *testing.B) {
// 	var myID int32

// 	b.Run("single/noinline", func(b *testing.B) {
// 		m := escapeToHeap(&id32{id: 6754}).(*id32)
// 		b.ResetTimer()
// 		for i := 0; i < b.N; i++ {
// 			// Call "".(*int32).idNoInline(SB)
// 			// MOVL 8(SP),AX
// 			// MOVQ "".&myID+40(SP), CX
// 			// MOVL AX, (CX)
// 			myID = m.idNOInline()
// 		}
// 	})

// 	b.Run("single/inline", func(b *testing.B) {
// 		m := escapeToHeap(&id32{id: 6754}).(*id32)
// 		b.ResetTimer()
// 		for i := 0; i < b.N; i++ {
// 			// MOVL (DX),SI
// 			// MOVL SI,(CX)
// 			myID = m.idNOInline()
// 		}
// 	})
// }

// //接口调用
// func BenchamarkMethodCall_interface(b *testing.B) {
// 	var myID int32

// 	b.Run("single/noinline", func(b *testing.B) {
// 		m := escapeToHeap(&id32{id: 6754})
// 		b.ResetTimer()
// 		for i := 0; i < b.N; i++ {
// 			// MOVQ 32(AX),CX
// 			// MOVQ "".M.data+40(SP),DX
// 			// MOVQ DX, (SP)
// 			// CALL CX
// 			// MOVL 8 (SP),AX
// 			// MOVL "".myId +48(SP),CX
// 			// MOVL AX,(CX)
// 			myID = m.idNOInline()
// 		}
// 	})

// 	b.Run("single/inline", func(b *testing.B) {
// 		m := escapeToHeap(&id32{id: 6754}).(*id32)
// 		b.ResetTimer()
// 		for i := 0; i < b.N; i++ {
// 			// MOVQ 24(AX),CX
// 			// MOVQ "".M.data+40(SP),DX
// 			// MOVQ DX,(SP)
// 			// CALL CX
// 			// MOVL 8(SP),AX
// 			// MOVQ "".&myID+48(SP), CX
// 			// MOVL AX,(CX)
// 			myID = m.idNOInline()
// 		}
// 	})
// }

// func main() {

// }
//===============================================

// import (
// 	"runtime"
// 	"time"
// )

// func main() {
// 	go func() {
// 		sum := 0
// 		for i := 0; i < 10000; i++ {
// 			sum += i
// 		}
// 		println(sum)
// 		time.Sleep(1 * time.Second)
// 	}()

// 	//NumGoroutine 可以返回当前程序的goroutine数目
// 	println("NumGoroutime=", runtime.NumGoroutine())

// 	//main goroutine故意 ”sleep“5秒，防止其提前退出
// 	time.Sleep(5 * time.Second)
// }

//===============================================

// import (
// 	"runtime"
// 	"time"
// )

// func sum() {

// 	sum := 0
// 	for i := 0; i < 10000; i++ {
// 		sum += i
// 	}
// 	println(sum)
// 	time.Sleep(1 * time.Second)
// }

// func main() {

// 	go sum()

// 	//NumGoroutine 可以返回当前程序的goroutine数目
// 	println("NumGoroutime=", runtime.NumGoroutine())

// 	//main goroutine故意 ”sleep“5秒，防止其提前退出
// 	time.Sleep(5 * time.Second)
// }
//===============================================

// import "runtime"

// func main() {
// 	//获取当前的GOMAXPROCS值
// 	println("GOMAXPROCS=", runtime.GOMAXPROCS(0))
// 	//获取当前的GOMAXPROCS值为2
// 	runtime.GOMAXPROCS(2)

// 	//获取当前的GOMAXPROCS值
// 	println("GOMAXPROCS=", runtime.GOMAXPROCS(0))
// }
//===============================================

// import "runtime"

// func main() {
// 	c := make(chan struct{})
// 	go func(i chan struct{}) {
// 		sum := 0
// 		for i := 0; i < 10000; i++ {
// 			sum += i
// 		}
// 		println(sum)
// 		//写通道
// 		c <- struct{}{}
// 	}(c)

// 	//NumGoroutine可以返回当前程序的goroutine数目
// 	println("NumGoroutine=", runtime.NumGoroutine())

// 	//读通道c，通过通道进行同步等待
// 	<-c
// }

//
//===============================================
// import (
// 	"net/http"
// 	"sync"
// )

// var wg sync.WaitGroup
// var urls = []string{
// 	"http://www.sina.com.cn/",
// 	"http://www.baidu.com/",
// 	"https://www.163.com/",
// }

// func main() {
// 	for _, url := range urls {
// 		//每个URL启动一个goroutine，同时给wg加1
// 		wg.Add(1)

// 		//Launch a goroutine to fetch the URL.
// 		go func(url string) {
// 			//当前goroutine结束后给wg计数减1，wg.Done()等价于wg.Add(-1)
// 			//defer wg.Add(-1)
// 			defer wg.Done()

// 			//发送HTTP get请求并打印HTTP返回码
// 			resp, err := http.Get(url)
// 			if err == nil {
// 				println(resp.Status)
// 			}
// 		}(url)
// 	}

// 	//等待所有请求结束
// 	wg.Wait()
// }
//===============================================

// func main() {
// 	ch := make(chan int, 1)
// 	go func(chan int) {
// 		for {
// 			select {
// 			// 0或1的吸入是随机的
// 			case ch <- 0:
// 			case ch <- 1:
// 			}
// 		}
// 	}(ch)

// 	for i := 0; i < 10; i++ {
// 		println(<-ch)
// 	}
// }
//===============================================
// import (
// 	"fmt"
// 	"math/rand"
// 	"runtime"
// )

// //GeneratIntA是一个随机数生产器
// func GenerateIntA(done chan struct{}) chan int {
// 	ch := make(chan int)
// 	go func() {
// 	Lable:
// 		for {
// 			select {
// 			case ch <- rand.Int():
// 				//增加一路监听，就是对退出通知信号done的监听
// 			case <-done:
// 				break Lable
// 			}
// 		}
// 		//收到通知后关闭通道ch
// 		close(ch)
// 	}()
// 	return ch
// }

// func main() {
// 	done := make(chan struct{})
// 	ch := GenerateIntA(done)

// 	fmt.Println(<-ch)
// 	fmt.Println(<-ch)

// 	//发送通知，告诉生产者停止生产
// 	close(done)

// 	fmt.Println(<-ch)
// 	fmt.Println(<-ch)

// 	//此时生产者已经退出
// 	println("NumGoroutine=", runtime.NumGoroutine())
// }
//===============================================

// import (
// 	"fmt"
// 	"math/rand"
// 	"time"
// )

// func GenerateIntA() chan int {
// 	ch := make(chan int, 10)
// 	//启动一个goroutine用于生成随机数，函数返回一个通道用于获取随机数
// 	go func() {
// 		for {
// 			ch <- rand.Int() * time.Now().Nanosecond()
// 		}
// 	}()
// 	return ch
// }

// func main() {
// 	ch := GenerateIntA()
// 	fmt.Println(<-ch)
// 	fmt.Println(<-ch)
// }
//===============================================

// import (
// 	"fmt"
// 	"math/rand"
// 	"time"
// )

// func GenerateIntA() chan int {
// 	ch := make(chan int, 10)
// 	//启动一个goroutine用于生成随机数，函数返回一个通道用于获取随机数
// 	go func() {
// 		for {
// 			ch <- rand.Int() * time.Now().Nanosecond()
// 		}
// 	}()
// 	return ch
// }

// func GenerateIntB() chan int {
// 	ch := make(chan int, 10)
// 	go func() {
// 		for {
// 			ch <- rand.Int() * time.Now().Nanosecond()
// 		}
// 	}()
// 	return ch
// }

// func GenerateInt() chan int {
// 	ch := make(chan int, 20)
// 	go func() {
// 		for {
// 			//使用select的扇入技术（Fan in）增加生成的随机源
// 			select {
// 			case ch <- <-GenerateIntA():
// 			case ch <- <-GenerateIntB():
// 			}

// 		}
// 	}()
// 	return ch
// }

// func main() {
// 	ch := GenerateInt()

// 	for i := 0; i < 100; i++ {
// 		fmt.Print(i, ". ")
// 		fmt.Println(<-ch)
// 	}
// }

// import (
// 	"fmt"
// 	"math/rand"
// 	"time"
// )

// func GenerateIntA(done chan struct{}) chan int {
// 	ch := make(chan int)
// 	go func() {
// 	Lable:
// 		for {
// 			//通过select监听一个信号chan来确定是否停止生成
// 			select {
// 			case ch <- rand.Int() * time.Now().Nanosecond():
// 			case <-done:
// 				break Lable
// 			}
// 		}
// 		close(ch)

// 	}()
// 	return ch
// }

// func main() {
// 	done := make(chan struct{})
// 	ch := GenerateIntA(done)

// 	fmt.Println(<-ch)
// 	fmt.Println(<-ch)

// 	//不再需要生成器，通过close chan发送一个通知给生成器
// 	close(done)
// 	for v := range ch {
// 		fmt.Println(v)
// 	}
// }
//===============================================

// import (
// 	"fmt"
// 	"math/rand"
// 	"time"
// )

// //done接受通知退出信号
// func GenerateIntA(done chan struct{}) chan int {
// 	ch := make(chan int, 5)
// 	go func() {
// 	Lable:
// 		for {
// 			select {
// 			case ch <- rand.Int() * time.Now().Nanosecond():
// 			case <-done:
// 				break Lable
// 			}
// 		}
// 		close(ch)
// 	}()
// 	return ch
// }

// //done接收通知退出信号
// func GenerateIntB(done chan struct{}) chan int {
// 	ch := make(chan int, 10)
// 	go func() {
// 	Lable:
// 		for {
// 			select {
// 			case ch <- rand.Int() * time.Now().Nanosecond():
// 			case <-done:
// 				break Lable
// 			}
// 		}
// 		close(ch)
// 	}()
// 	return ch
// }

// //通过select执行扇入（Fan in）操作
// func GenerateInt(done chan struct{}) chan int {
// 	ch := make(chan int)
// 	send := make(chan struct{})
// 	go func() {
// 	Lable:
// 		for {
// 			select {
// 			case ch <- <-GenerateIntA(send):
// 			case ch <- <-GenerateIntB(send):
// 			case <-done:
// 				send <- struct{}{}
// 				send <- struct{}{}
// 				break Lable
// 			}
// 		}
// 		close(ch)
// 	}()
// 	return ch
// }

// func main() {
// 	//创建一个作为接收退出信号的chan
// 	done := make(chan struct{})

// 	//启动生成器
// 	ch := GenerateInt(done)

// 	//获取生成器资源
// 	for i := 0; i < 10; i++ {
// 		fmt.Print(i, ". ")
// 		fmt.Println(<-ch)
// 	}

// 	//通知生产者停止生产
// 	done <- struct{}{}
// 	fmt.Println("stop gernarate")
// }
//===============================================

// import "fmt"

// //chain函数的输入参数和输出参数类型相同，都是chan int类型
// //chain函数的功能是将chan内的数据统一加1

// func chain(in chan int) chan int {
// 	out := make(chan int)
// 	go func() {
// 		for v := range in {
// 			out <- 3 + v
// 		}
// 		close(out)
// 	}()
// 	return out
// }

// func main() {
// 	in := make(chan int)

// 	//初始化输入参数
// 	go func() {
// 		for i := 0; i < 10; i++ {
// 			in <- i
// 		}
// 		close(in)
// 	}()

// 	//连续调用3次chan，相当于把in中的每个元素都加3
// 	out := chain(chain(chain(in)))
// 	for v := range out {
// 		fmt.Println(v)
// 	}
// }
//===============================================
// import (
// 	"fmt"
// 	"sync"
// 	"time"
// )

// //工作任务
// type task struct {
// 	begin  int
// 	end    int
// 	result chan<- int
// }

// //任务执行：计算begin到end的和
// //执行结果写入结果 chan result
// func (t *task) do() {
// 	sum := 0
// 	for i := t.begin; i <= t.end; i++ {
// 		sum += i
// 	}
// 	t.result <- sum
// }

// func main() {
// 	start := time.Now()
// 	//创建任务通道
// 	taskchan := make(chan task, 10)

// 	//创建结果通道
// 	resultchan := make(chan int, 10)

// 	//wait用于同步等待任务的执行
// 	wait := &sync.WaitGroup{}

// 	//初始化task的goroutine，计算100个自然数之和
// 	go InitTask(taskchan, resultchan, 10000)

// 	//每个task启动一个goroutine进行处理
// 	go DistributeTask(taskchan, wait, resultchan)

// 	//通过结果通道获取结果并汇总
// 	sum := ProcessResult(resultchan)

// 	fmt.Println("sum=", sum)
// 	cost := time.Since(start)
// 	fmt.Printf("cost=%s\n", cost)
// }

// //构建task并写入task通道
// func InitTask(taskchan chan<- task, r chan int, p int) {
// 	qu := p / 10
// 	mod := p % 10
// 	high := qu * 10
// 	for j := 0; j < qu; j++ {
// 		b := 10*j + 1
// 		e := 10 * (j + 1)
// 		tsk := task{
// 			begin:  b,
// 			end:    e,
// 			result: r,
// 		}
// 		taskchan <- tsk
// 	}
// 	if mod != 0 {
// 		tsk := task{
// 			begin:  high + 1,
// 			end:    p,
// 			result: r,
// 		}
// 		taskchan <- tsk
// 	}
// 	close(taskchan)
// }

// //读取task chan，每个task启动一个worker goroutine进行处理
// // 并等待每个task运行完，关闭结果通道
// func DistributeTask(taskchan <-chan task, wait *sync.WaitGroup, result chan int) {
// 	for v := range taskchan {
// 		wait.Add(1)
// 		go ProcessTask(v, wait)
// 	}
// 	wait.Wait()
// 	close(result)
// }

// //goroutine处理具体工作，并将处理结果发送到结果通道
// func ProcessTask(t task, wait *sync.WaitGroup) {
// 	t.do()
// 	wait.Done()
// }

// //读取结果通道，汇总结果
// func ProcessResult(resultchan chan int) int {
// 	sum := 0
// 	for r := range resultchan {
// 		sum += r
// 	}

// 	return sum
// }
//===============================================

// import (
// 	"fmt"
// 	"time"
// )

// //工作池的goroutine数目
// const (
// 	NUMBER = 10
// )

// //工作任务
// type task struct {
// 	begin  int
// 	end    int
// 	result chan<- int
// }

// //任务执行：计算begin到end的和
// //执行结果写入结果 chan result
// func (t *task) do() {
// 	sum := 0
// 	for i := t.begin; i <= t.end; i++ {
// 		sum += i
// 	}
// 	t.result <- sum
// }

// func main() {
// 	start := time.Now()
// 	workers := NUMBER

// 	//工作通道
// 	taskchan := make(chan task, 10)

// 	//结果通道
// 	resultchan := make(chan int, 10)

// 	//worker信号通道
// 	done := make(chan struct{}, 10)

// 	//初始化task的goroutine，计算100个自然数之和
// 	go InitTask(taskchan, resultchan, 100)

// 	//分发任务到NUMBER个goroutine池
// 	DistributeTask(taskchan, workers, done)

// 	go CloseResult(done, resultchan, workers)

// 	//通过结果通道获取结果并汇总
// 	sum := ProcessResult(resultchan)

// 	fmt.Println("sum=", sum)
// 	cost := time.Since(start)
// 	fmt.Printf("cost=%s\n", cost)
// }

// //初始化待处理task chan
// func InitTask(taskchan chan<- task, r chan int, p int) {
// 	qu := p / 10
// 	mod := p % 10
// 	high := qu * 10
// 	for j := 0; j < qu; j++ {
// 		b := 10*j + 1
// 		e := 10 * (j + 1)
// 		tsk := task{
// 			begin:  b,
// 			end:    e,
// 			result: r,
// 		}
// 		taskchan <- tsk
// 	}
// 	if mod != 0 {
// 		tsk := task{
// 			begin:  high + 1,
// 			end:    p,
// 			result: r,
// 		}
// 		taskchan <- tsk
// 	}
// 	close(taskchan)
// }

// //读取task chan，并分发到worker goroutine处理，总的数量是workers
// func DistributeTask(taskchan <-chan task, workers int, done chan struct{}) {
// 	for i := 0; i < workers; i++ {
// 		go ProcessTask(taskchan, done)
// 	}
// }

// //goroutine处理具体工作，并将处理结果发送到结果通道
// func ProcessTask(taskchan <-chan task, done chan struct{}) {
// 	for t := range taskchan {
// 		t.do()
// 	}
// 	done <- struct{}{}
// }

// //通过done channel同步等待所有工作goroutine的结果，然后关闭结果chan
// func CloseResult(done chan struct{}, resultchan chan int, workers int) {
// 	for i := 0; i < workers; i++ {
// 		<-done
// 	}

// 	close(done)
// 	close(resultchan)
// }

// //读取结果通道，汇总结果
// func ProcessResult(resultchan chan int) int {
// 	sum := 0
// 	for r := range resultchan {
// 		sum += r
// 	}

// 	return sum
// }

//===============================================

// import (
// 	"fmt"
// 	"time"
// )

// //一个查询结构体
// //这里的sql和result是一个简单的抽象，具体的应用可能是更复制的数据类型
// type query struct {
// 	//参数 channel
// 	sql chan string

// 	//结果channel
// 	result chan string
// }

// //执行Query
// func execQuery(q query) {

// 	//启动协程
// 	go func() {
// 		//获取输入
// 		sql := <-q.sql

// 		//访问数据库

// 		//输出结果通道
// 		q.result <- "result from " + sql
// 	}()
// }

// func main() {

// 	//初始化 Query
// 	q := query{make(chan string, 1), make(chan string, 1)}

// 	//执行Query，注意执行的时候无须准备参数
// 	go execQuery(q)

// 	//发送参数
// 	q.sql <- "select * from table"

// 	//做其他事情，通过sleep描述
// 	time.Sleep(1 * time.Second)

// 	//获取结果
// 	fmt.Println(<-q.result)

// }
//===============================================
// type Context interface {
// 	//如果Context实现了超时控制，则该方法返回ok true，deadline为超时时间，
// 	//否则ok为false
// 	Deadline() (deadline time.Time, ok bool)

// 	//后端被调用的goroutine应该监听该方法返回的chan，以便及时释放资源
// 	Done() <-chan struct{}

// 	//Done返回的chan收到通知的时候，才可以访问Err()获知因为什么原因被取消
// 	Err() error

// 	//可以访问上游goroutine传递给下游goroutine的值
// 	Value(key interface{}) interface{}
// }
//===============================================
//一个context对象如果实现了canceler接口，则可以被取消

// type canceler interface {
// 	//创建cancel接口实例的goroutine条用cancel方法通知后续创建的goroutine退出
// 	cancel(removeFromParent bool, err error)

// 	//Done方法返回的chan需要后端goroutine来监听，并及时退出
// 	Done() <-chan struct{}
// }
//===============================================

// //emptyCtx实现了Context接口
// type emptyCtx int

// func(*emptyCtx) Deadline()(deadline time.Time, ok bool){
// 	return
// }

// func(*emptyCtx) Don()<-chan struct{}){
// 	return nil
// }

// func (*emptyCtx) Err() error{
// 	return nil
// }

// func (*emptyCtx) Value(key interface{}) interface{}{
// 	return nil
// }

// func (e *emptyCtx) String() string{
// 	switch e {
// 	case background:
// 		return "context.Background"
// 	case todo:
// 		return "context.TODO"
// 	}

// 	return "unknown empty Context"
// }
//===============================================
// var (
// 	background = new (emptyCtx)
// 	todo = new(emptyCtx)
// )

// func Background() Context{
// 	return background
// }

// func TODO() Context{
// 	return todo
// }
//===============================================

// //cancelCTx可以被取消，cancelCtx取消时会同时取消所有实现canceler接口的汉字节点
// type cancelCtx struct {
// 	Context

// 	done chan struct{} //closed by the first cancel call.

// 	mu       sync.Mutex
// 	children map[canceler]bool //set to nil by the first cancel call
// 	err      error             //set to non-nil by the first cancel call
// }

// func (c *cancelCtx) Done() <-chan struct{} {
// 	return c.done
// }

// func (c *cancelCtx) Err() error {
// 	c.mu.Lock()
// 	defer c.mu.Unlock()
// 	return c.err
// }

// func (c *cancelCtx) String() string {
// 	return fmt.Sprintf("%v.WithCancel", c.Context)
// }

// //cancel closes c.done, cancels each of c's children,and, if
// // removeFromParent is true,removes c form its parent's children
// func (c *cancelCtx) cancel(removeFromParent bool, err error) {
// 	if err==nil {
// 		panic("context:internal error:missing cancel error")
// 	}
// 	c.mu.Lock()
// 	if c.err !=nil {
// 		c.mu.Unlock()
// 		return //already canceled
// 	}
// 	c.err =err
// 	//显示通知自己
// 	close(c.done)

// 	//循环调用children的cancel函数，由于parent已经取消，所以此时child调用
// 	//cancel传入的时false
// 	for child := range c.children {
// 		//NOTE:acquiring the child's lock while holding parent's lock
// 		child.cancel(false,err)
// 	}
// 	c.children = nil
// 	c.mu.Unlock()

// 	if removeFromParent {
// 		removeChild(c.Context,c)
// 	}
// }
// //===============================================
// type timeerCtx struct {
// 	cancelCtx
// 	timer *time.Timer // Under cancelCtx.mu.

// 	deadline time.Time
// }

// func (c *timerCtx) Deadline() (deadline time.Time, ok bool) {
// 	return c.deadline, true
// }

// func (c *timerCtx) String() string {
// 	return fmt.Sprint("%v.WithDeadline(%s [%s])", c.cancelCtx, c.deadline, c.deadline.Sub(time.Now()))
// }

// func (c *timeerCtx) cancel(removeFromParent bool, err error) {
// 	c.cancelCtx.cancel(false, err)
// 	if removeFromParent {
// 		//Remove this timerCtx from its parent cancelCtx's children
// 		removeChild(c.cancelCtx.Context, c)
// 	}
// 	c.mu.Lock()
// 	if c.timer != nil {
// 		c.timer.Stop()
// 		c.timer = nil
// 	}
// 	c.mu.Unlock()
// }
//===============================================

// type valueCtx struct {
// 	Context
// 	key, val interface{}
// }

// func (c *valueCtx) String() string {
// 	return fmt.Sprintf("%v.WithValue(%#v,%#v)", c.Context, c.key, c.val)
// }

// func (c *valueCtx) Value(key interface{}) interface{} {
// 	if c.key == key {
// 		return c.val
// 	}
// 	return c.Context.Value(key)
// }
//===============================================
// func propagateCancel(parent Context, Child canceler) {
// 	if parent.Done() == nil {
// 		return //parent is never canceld
// 	}
// 	if p, ok := parentCancelCtx(parent); ok {
// 		p.mu.Lock()
// 		if p.err!=nil {
// 			//parent has already benn canceled
// 			child.cancel(false, p.err)
// 		} else {
// 			if p.children == nil {
// 				p.children = make(map[canceler]bool)
// 			}
// 			//维护parent和child的关系
// 			p.children[child] = true

// 		}
// 		p.mu.Unlokc()
// 	} else {
// 		go func(){
// 			select {
// 			case <- parent.Done():
// 				child.cancel(false,Parent.Err())
// 			case<-Child.Done():
// 			}
// 		}()
// 	}
// }

//===============================================
// func parentCancelCtx(parent Context) (*cancelCtx,bool){
// 	for {
// 		switch c:=parent.(type) {
// 		case *cancelCtx:
// 			return c,true
// 		case *timerCtx:
// 			return &c.cancelCtx,true
// 		case *valueCtx:
// 			parent = c.Context
// 		default:
// 			return nil,false
// 		}
// 	}
// }
//===============================================
// //removeChild removes a context from its parent.
// func removeChild(parent Context, child canceler) {
// 	p, ok := parentCancelCtx(parent)
// 	if !ok {
// 		return
// 	}
// 	p.mu.Lock()
// 	if p.children != nil {
// 		delete(p.children, child)
// 	}
// 	p.mu.Unlock()
// }
//===============================================
// import (
// 	"context"
// 	"fmt"
// 	"time"
// )

// //define a new type include a Context Field
// type otherContext struct {
// 	context.Context
// }

// func main() {
// 	//使用context.Background()构建一个WithCancel类型的上下文
// 	ctxa, cancel := context.WithCancel(context.Background())

// 	//work模拟运行并检查前端的退出通知
// 	go work(ctxa, "work1")

// 	//使用WithDeadline包装前面的上下文对象ctxa
// 	tm := time.Now().Add(3 * time.Second)
// 	ctxb, _ := context.WithDeadline(ctxa, tm)

// 	go work(ctxb, "work2")

// 	//使用WithValue包装前面的上下文对象ctxb
// 	oc := otherContext{ctxb}
// 	ctxc := context.WithValue(oc, "key", "andes,pass from main")

// 	go workWithValue(ctxc, "work3")

// 	//故意 "sleep" 10秒，让work2、work3超时退出
// 	time.Sleep(10 * time.Second)

// 	//显示调用work1的cancel方法通知其退出
// 	cancel()

// 	//等待work1打印退出信息
// 	time.Sleep(5 * time.Second)
// 	fmt.Println("main stop")
// }

// //do something
// func work(ctx context.Context, name string) {
// 	for {
// 		select {
// 		case <-ctx.Done():
// 			fmt.Printf("%s get msg to cancel\n", name)
// 			return
// 		default:
// 			fmt.Printf("%s is running \n", name)
// 			time.Sleep(1 * time.Second)
// 		}
// 	}
// }

// //等待前端的退出通知，并试图获取Context传递的数据
// func workWithValue(ctx context.Context, name string) {
// 	for {
// 		select {
// 		case <-ctx.Done():
// 			fmt.Printf("%s get msg to cancel\n", name)
// 			return
// 		default:
// 			value := ctx.Value("key").(string)
// 			fmt.Printf("%s is running value=%s \n", name, value)
// 			time.Sleep(1 * time.Second)
// 		}
// 	}
// }
//===============================================
// // $GOROOT src/reflect/type.go
// type rtype struct{
// 	size uintptr
// 	ptrdata uintptr //number of bytes in the type that can contain pointers
// 	hash uint32 // hash of type;avoids computation in hash tables
// 	tflag tflag //extra type information flags
// 	align uint8 //alignment of variable with this type
// 	fieldAlign uint8 //alignment of struct field with this type
// 	kind uint8 //enumeration for c
// 	alg *typeAlg //algorithm table
// 	gcdata *byte //garbage collection data
// 	str nameOff //string form
// 	ptrToThis typeOff //type for pointer to this type, may be zero
// }

// //数组类型
// type arrayType struct {
// 	rtype `reflect:"array"`
// 	elem *rtype //array element type
// 	slice *rtype //slice type
// 	len uintptr
// }

// //指针类型
// //ptrType represents a pointer type.
// type ptrType struct {
// 	rtype `reflect:"ptr"`
// 	elem *rtype //pointer element (pointed at) type
// }
//===============================================

// import (
// 	"fmt"
// 	"reflect"
// )

// type Student struct {
// 	Name string "学生姓名"
// 	Age  int    `a:"1111"b:"3333"`
// }

// func main() {
// 	s := Student{}
// 	rt := reflect.TypeOf(s)
// 	fieldName, ok := rt.FieldByName("Name")

// 	//取tag数据
// 	if ok {
// 		fmt.Println(fieldName.Tag)
// 	}

// 	fieldAge, ok2 := rt.FieldByName("Age")

// 	// 可以像JSON一样，取tag里的数据，多个tag之间无逗号，tag不需要引号
// 	if ok2 {
// 		fmt.Println(fieldAge.Tag.Get("a"))
// 		fmt.Println(fieldAge.Tag.Get("b"))
// 	}

// 	fmt.Println("type_Name:", rt.Name())
// 	fmt.Println("type_NumField:", rt.NumField())
// 	fmt.Println("type_PkgPath:", rt.PkgPath())
// 	fmt.Println("type_String:", rt.String())
// 	fmt.Println("type.Kind.String:", rt.Kind().String())
// 	fmt.Println("Kind.String()=", rt.Kind().String())

// 	//获取结构类型的字段名称
// 	for i := 0; i < rt.NumField(); i++ {
// 		fmt.Printf("tyoe.Field[%d].Name:=%v \n", i, rt.Field(i).Name)
// 	}

// 	sc := make([]int, 10)
// 	sc = append(sc, 1, 2, 3)
// 	sct := reflect.TypeOf(sc)

// 	//获取slice元素的Type
// 	scet := sct.Elem()
// 	fmt.Println("slice element type.Kind()", scet.Kind())
// 	fmt.Printf("slice element type.Kind()=%d\n", scet.Kind())
// 	fmt.Println("slice element type.String()=", scet.String())
// 	fmt.Println("slice element type.Name()=", scet.Name())
// 	fmt.Println("slice element type.NumMethod()=", scet.NumMethod())
// 	fmt.Println("slice element type.PkgPath()=", scet.PkgPath())
// 	fmt.Println("slice element type.PkgPath()=", scet.PkgPath())
// }
//===============================================

// import "reflect"

// type INT int

// type A struct {
// 	a int
// }

// type B struct {
// 	b string
// }

// type Ita interface {
// 	String() string
// }

// func (b B) String() string {
// 	return b.b
// }

// func main() {
// 	var a INT = 12
// 	var b int = 14

// 	//实参时具体类型，reflect.TypeOf返回是其静态类型
// 	ta := reflect.TypeOf(a)
// 	tb := reflect.TypeOf(b)

// 	//INT 和int是两个类型，二者不相等
// 	if ta == tb {
// 		println("ta == tb")
// 	} else {
// 		println("ta ！= tb")
// 	}

// 	println(ta.Name())
// 	println(tb.Name())

// 	//底层基础类型
// 	println(ta.Kind().String())
// 	println(ta.Kind().String())

// 	s1 := A{1}
// 	s2 := B{"tata"}

// 	//实参是具体类型，reflect.TypeOf返回的是其静态类型
// 	println(reflect.TypeOf(s1).Name())
// 	println(reflect.TypeOf(s2).Name())

// 	//Type的Kind()方法返回的是基础类型，类型A和B的底层基础类型都是struct
// 	println(reflect.TypeOf(s1).Kind().String())
// 	println(reflect.TypeOf(s2).Kind().String())

// 	ita := new(Ita)
// 	var itb Ita = s2

// 	//实参是未绑定具体变量的接口类型，reflect.TypeOf返回的是接口类型本身
// 	//也就是接口的静态类型
// 	println(reflect.TypeOf(ita).Elem().Name())
// 	println(reflect.TypeOf(ita).Elem().Kind().String())

// 	//实参是绑定具体变量的接口类型，reflect.TypeOf返回的是绑定的具体类型
// 	//也就是接口的静态类型
// 	println(reflect.TypeOf(itb).Name())
// 	println(reflect.TypeOf(itb).Kind().String())
// }
//===============================================
// import (
// 	"fmt"
// 	"reflect"
// )

// type User struct {
// 	Id   int
// 	Name string
// 	Age  int
// }

// func (this User) String() {
// 	println("User:", this.Id, this.Name, this.Age)
// }

// func Info(o interface{}) {
// 	//获取Value信息
// 	v := reflect.ValueOf(o)

// 	//通过Vlue获取Type
// 	t := v.Type()

// 	//类型名称
// 	println("Type:", t.Name())

// 	//访问接口字段名、字段类型和字段值信息
// 	println("Fields:")
// 	for i := 0; i < t.NumField(); i++ {
// 		field := t.Field(i)
// 		value := v.Field(i).Interface()

// 		//类型查询
// 		switch value := value.(type) {
// 		case int:
// 			fmt.Printf(" %6s: %v=%d\n", field.Name, field.Type, value)
// 		case string:
// 			fmt.Printf(" %6s: %v=%s\n", field.Name, field.Type, value)
// 		default:
// 			fmt.Printf(" %6s: %v=%d\n", field.Name, field.Type, value)
// 		}
// 	}
// }

// func main() {
// 	u := User{1,"tom",30}
// 	Info(u)
// }
//===============================================

// import (
// 	"fmt"
// 	"reflect"
// )

// type User struct {
// 	Id   int
// 	Name string
// 	Age  int
// }

// func main() {
// 	u := User{Id: 1, Name: "andes", Age: 20}

// 	va := reflect.ValueOf(u)
// 	vb := reflect.ValueOf(&u)

// 	//值类型是可修改的
// 	fmt.Println(va.CanSet(), va.FieldByName("Name").CanSet()) //false

// 	//指针类型是可修改的
// 	fmt.Println(vb.CanSet(), vb.Elem().FieldByName("Name").CanSet()) //true

// 	fmt.Printf("%v\n", vb)
// 	name := "shine"
// 	vc := reflect.ValueOf(name)

// 	//通过Set函数修改变量的值
// 	vb.Elem().FieldByName("Name").Set(vc)
// 	fmt.Printf("%v\n", vb)
// }
//===============================================
// import (
// 	"fmt"

// 	"github.com/codegangsta/inject"
// )

// type S1 interface{}
// type S2 interface{}

// func Format(name string, company S1, level S2, age int) {
// 	fmt.Printf("name=%s,company=%s,level=%s,age=%d!\n", name, company, level, age)
// }

// func main() {

// 	//控制实例的创建
// 	inj := inject.New()

// 	//实参注入
// 	inj.Map("tom")
// 	inj.MapTo("tencent", (*S1)(nil))
// 	inj.MapTo("T4", (*S2)(nil))
// 	inj.Map(23)

// 	//函数反转调用
// 	inj.Invoke(Format)
// }
//===============================================

// import (
// 	"fmt"

// 	"github.com/codegangsta/inject"
// )

// type S1 interface{}
// type S2 interface{}

// type Staff struct {
// 	Name    string `inject`
// 	Company S1     `inject`
// 	Level   S2     `inject`
// 	Age     int    `inject`
// }

// func main() {

// 	//创建被注入实例
// 	s := Staff{}

// 	//控制实例的创建
// 	inj := inject.New()

// 	//初始化注入值
// 	inj.Map("tom")
// 	inj.MapTo("tencent", (*S1)(nil))
// 	inj.MapTo("T4", (*S2)(nil))
// 	inj.Map(23)

// 	//实现对struct注入
// 	inj.Apply(&s)

// 	//打印结果
// 	fmt.Printf("s=%v\n", s)
// }
//===============================================
// import "sync"

// func main() {
// 	wg := sync.WaitGroup{}
// 	si := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

// 	for i := range si {
// 		wg.Add(1)
// 		go func() {
// 			println(i)
// 			wg.Done()
// 		}()
// 	}
// 	wg.Wait()
// }
//===============================================
// import "sync"

// func main() {
// 	wg := sync.WaitGroup{}
// 	si := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

// 	for i := range si {
// 		wg.Add(1)

// 		//这里有一个实参到形参的值拷贝
// 		go func(a int) {
// 			println(a)
// 			wg.Done()
// 		}(i)
// 	}
// 	wg.Wait()
// }
//===============================================

// func f1() (r int) {
// 	defer func() {
// 		r++
// 	}()
// 	return 0
// }

// func f2() (r int) {
// 	t := 5
// 	defer func() {
// 		t = t + 5
// 	}()
// 	return t
// }

// func f3() (r int) {
// 	defer func(r int) {
// 		r = r + 5
// 	}(r)
// 	return 1
// }

// func main() {
// 	println("f1=", f1()) //f1=1
// 	println("f2=", f2()) //f1=5
// 	println("f3=", f3()) //f1=1
// }
//===============================================
// func f4() int {
// 	r := 0
// 	defer func() {
// 		r++
// 	}()
// 	return r
// }

// func f5() int {
// 	r := 0
// 	defer func(i int) {
// 		i++
// 	}(r)
// 	return 0
// }

// func main() {
// 	println("f4=", f4())
// 	println("f5=", f5())
// }
//===============================================
// import "fmt"
// func main() {
// 	//指定大小的显示初始化
// 	a := [3]int{1, 2, 3}

// 	//通过“...”由后面的元素个数推断数组大小
// 	b:=[...]int{1,2,3}

// 	//指定大小，并通过索引值初始化，未显示初始化的元素被置位“零值”
// 	c:=[3]int{1:1,2:3}

// 	//指定大小但不显示初始化，数组元素全被置为”零值“
// 	var d [3]int

// 	fmt.Printf("len=%d,value=%v\n", len(a),a)
// 	fmt.Printf("len=%d,value=%v\n", len(b),b)
// 	fmt.Printf("len=%d,value=%v\n", len(c),c)
// 	fmt.Printf("len=%d,value=%v\n", len(d),d)
// }
//===============================================
// import "fmt"
// func f(a [3]int){
// 	a[2] = 10
// 	fmt.Printf("%p,%v\n",&a,a)

// }

// func main(){
// 	a:=[3]int{1,2,3}
// 	//直接赋值时拷贝

// 	b:=a

// 	//修改a元素值并不影响b
// 	a[2] =4

// 	fmt.Printf("%p,%v\n",&a,a)
// 	fmt.Printf("%p,%v\n",&b,b)

// 	//数组作为函数参数仍然是只拷贝
// 	f(a)

// 	c:=struct{
// 		s [3]int

// 	}{
// 		s:a,
// 	}

// 	//结构是值拷贝，内部的数组也是值拷贝
// 	d:=c

// 	//修改c中的数组元素值并不影响a
// 	c.s[2] = 30

// 	//修改d中的数组元素并不影响d
// 	d.s[2]= 20

// 	fmt.Printf("%p,%v\n",&a,a)
// 	fmt.Printf("%p,%v\n",&c,c)
// 	fmt.Printf("%p,%v\n",&d,d)

// }
//===============================================
// import (
// 	"fmt"
// 	"reflect"
// 	"unsafe"
// )

// func main() {
// 	var a []int
// 	b := make([]int, 0)

// 	if a == nil {
// 		fmt.Println("a is nul")
// 	} else {
// 		fmt.Println("a is not nul")
// 	}

// 	//虽然b的底层数组大小为0，但切片并不是nil
// 	if b == nil {
// 		fmt.Println("b is nil")
// 	} else {
// 		fmt.Println("b is not nil")
// 	}

// 	//使用反射中的SliceHeader来获取切片运行时的数据结构
// 	as := (*reflect.SliceHeader)(unsafe.Pointer(&a))
// 	bs := (*reflect.SliceHeader)(unsafe.Pointer(&b))

// 	fmt.Printf("len=%d,cap=%d,type=%d\n", len(a), cap(a), as.Data)
// 	fmt.Printf("len=%d,cap=%d,type=%d\n", len(b), cap(b), bs.Data)
// }
//===============================================

// m:=make(map[string]string)

// v, ok :=m["some"]
// //通过ok进行判断
// if!ok {
// 	println("m[some] is nil")
// } else {
// 	println("m[some] =", v)
// }
//===============================================
// c:=make(chan int)

// func main() {
// 	c <-1
// 	c<-2
// 	close(c)
// }()

// for {
// 	//使用comma，ok判断通道是否关闭
// 	v,ok:<-c
// 	if ok {
// 		println(v)
// 	}else {
// 		break
// 	}
// }

// //使用range更加简洁
// for v:=range c{
// 	println(v)
// }

import (
	"fmt"
	"runtime"
)

func main() {
	fmt.Printf("OS:%S\nArchitecutre:%s\n", runtime.GOOS, runtime.GOARCH)
}
